package com.kuaimacode.kframework.admin.services.user;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.kuaimacode.kframework.common.Constant;
import com.kuaimacode.kframework.component.ComponentUtil;
import com.kuaimacode.kframework.exception.ErrorEnum;
import com.kuaimacode.kframework.exception.ServerInternalErrorException;
import com.kuaimacode.kframework.mybatis.mapper.user.UserMapper;
import com.kuaimacode.kframework.mybatis.models.user.User;
import com.kuaimacode.kframework.mybatis.models.user.UserAccountDetail;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * @author Administrator
 * @date 2019/03/18
 */
@Service
public class UserService extends ServiceImpl<UserMapper, User> {

    @Autowired
    private ComponentUtil componentUtil;
    @Autowired
    private UserAccountDetailService userAccountDetailService;
    @Autowired
    private OrderService orderService;

    /**
     * 分页查找所有的数据
     *
     * @param pageNum  当前页码，从1开始
     * @param pageSize 一页显示多少行
     * @param searchUser
     * @return
     */
    public PageInfo<User> findAll(int pageNum, int pageSize, User searchUser) {
        PageHelper.startPage(pageNum, pageSize);
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        Optional.ofNullable(searchUser.getPhone())
                .filter(phone -> !"".equals(phone.trim())).ifPresent(phone -> queryWrapper.like("phone", phone));
        Optional.ofNullable(searchUser.getEnabled())
                .ifPresent(enable -> queryWrapper.eq("enabled", enable));
        Optional.ofNullable(searchUser.getIsMaster())
                .ifPresent(master -> queryWrapper.eq("is_master", master));
        Optional.ofNullable(searchUser.getIsCertifacate())
                .ifPresent(certificate -> queryWrapper.eq("is_certifacate", certificate));
        List<User> datas = baseMapper.selectList(queryWrapper);
        //处理图片地址
        Optional.ofNullable(datas)
                .ifPresent(users -> users.forEach(user -> {
                            Optional.ofNullable(user.getAvatarUrl())
                                    .ifPresent(url -> user.setAvatarUrl(componentUtil.convertImgUrl(url)));
                            //查询订单数
                            user.setUserOrderCount(orderService.userOrderCount(user.getId()));
                        }
                ));
        return new PageInfo<>(datas);
    }

    public User selectByName(String username) {

        QueryWrapper<User> qryWrapper = new QueryWrapper<>();
        qryWrapper.eq("username", username);

        return baseMapper.selectOne(qryWrapper);
    }

    public User selectByPhone(String phone) {
        QueryWrapper<User> qryWrapper = new QueryWrapper<>();
        qryWrapper.eq("phone", phone);
        return baseMapper.selectOne(qryWrapper);
    }

    /**
     * 查询合作商家列表
     * @param pageNum
     * @param pageSize
     * @param searchUser
     * @return
     */
    public PageInfo<User> findPartnerPage(int pageNum, int pageSize, User searchUser) {
        PageHelper.startPage(pageNum, pageSize);
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        Optional.ofNullable(searchUser.getPartnerName())
                .filter(partnerName -> !"".equals(partnerName.trim())).ifPresent(partnerName -> queryWrapper.like("partner_name", partnerName));
        queryWrapper.isNotNull("is_partner");
        List<User> datas = baseMapper.selectList(queryWrapper);
        return new PageInfo<>(datas);
    }

    /**
     * 修改商家信息
     * @param user
     * @return
     */
    public boolean editPartner(User user) {
        Optional.ofNullable(user.getId()).orElseThrow(() -> new ServerInternalErrorException(ErrorEnum.PARAM_VALID_ERROR));
        User partner = new User();
        Optional.ofNullable(user.getPartnerProtocol()).ifPresent(partner::setPartnerProtocol);
//        Optional.ofNullable(user.getIsPartner()).ifPresent(partner::setIsPartner);
        Optional.ofNullable(user.getPartnerAmount()).ifPresent(partner::setPartnerAmount);
        Optional.ofNullable(user.getPartnerRemark()).ifPresent(partner::setPartnerRemark);
        partner.setId(user.getId());
        return baseMapper.updateById(partner) == 1;
    }

    /**
     * 减少账户余额
     * @param userId
     * @param amount
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public void decreaseAccountBalance(Long userId, BigDecimal amount, String inOutType, String trandesc) {
        User user = baseMapper.selectById(userId);
        Optional.ofNullable(user)
                .orElseThrow(() -> new ServerInternalErrorException(ErrorEnum.USER_NOT_EXISTS));
        Optional.of(user)
                .filter(innerUser -> innerUser.getAccountBalance().compareTo(amount) > -1)
                .orElseThrow(() -> new ServerInternalErrorException(ErrorEnum.USER_BALANCE_NOT_ENOUGH));
        //增加明细记录
        UserAccountDetail insert = new UserAccountDetail();
        insert.setUserId(userId);
        insert.setAccountType(Constant.AccountTypeEnum.ACCOUNT.getCode().toString());
        insert.setDetailType("2");
        insert.setAmount(amount.toString());
        insert.setInOutType(inOutType);
        insert.setTranDesc(trandesc);
        insert.setStatus("1");
        Date now = new Date();
        insert.setCreateDt(now);
        insert.setUpdateDt(now);
        insert.setTranAmount(user.getAccountBalance().add(amount));
        userAccountDetailService.save(insert);

        User update = new User();
        update.setId(userId);
        update.setAccountBalance(user.getAccountBalance().add(amount));
        baseMapper.updateById(update);
    }

    public void agreePartner(Long id, BigDecimal scale) {
        User user = baseMapper.selectById(id);
        user.agreePartner(scale);
        baseMapper.updateById(user);
    }

    public void rejectPartner(Long id, String reason) {
        User user = baseMapper.selectById(id);
        user.rejectPartner(reason);
        baseMapper.updateById(user);
    }

    /**
     * 查询用户数量
     * param type 1-用户 2-师傅 3-合作商家
     * @return
     */
    public int userCount(Integer type) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("enabled", 1);
        switch(type){
            case 1:
                wrapper.ne("is_master", 2);//是否已认证为师傅 0 否 1 认证中 2已认证
                wrapper.ne("is_rider", 1);//是否同意骑手协议 0 否 1 是
                break;
            case 2:
                wrapper.eq("is_master", 2);//是否已认证为师傅 0 否 1 认证中 2已认证
                wrapper.eq("is_rider", 1);//是否同意骑手协议 0 否 1 是
                break;
            case 3:
                wrapper.eq("is_partner", 1);
                break;
            default:
        }
        return baseMapper.selectCount(wrapper);
    }

    /**
     * 用户总余额
     * param type 1-用户 2-师傅 3-合作商家
     * @return
     */
    public BigDecimal totalAmount(Integer type) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        switch(type){
            case 1:
                wrapper.ne("is_master", 2);//是否已认证为师傅 0 否 1 认证中 2已认证
                wrapper.ne("is_rider", 1);//是否同意骑手协议 0 否 1 是
                break;
            case 2:
                wrapper.eq("is_master", 2);//是否已认证为师傅 0 否 1 认证中 2已认证
                wrapper.eq("is_rider", 1);//是否同意骑手协议 0 否 1 是
                break;
            case 3:
                wrapper.eq("is_partner", 1);
                break;
            default:
        }

        List<User> list = baseMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(list)) {
            return BigDecimal.ZERO;
        }
        BigDecimal amount = new BigDecimal(0);
        for (User user : list) {
            amount = amount.add(user.getAccountBalance());
            if(type == 1){
                //用户时统计代收款
                amount = amount.add(user.getCollectBal());
            }
        }
        return amount;
    }
}

